#include "base.h"
#include "rect.h"
#include "Utils.h"
Rect::Rect()
{
	m_points = NULL;
	this->x = (float)0;
	this->y = (float)0;
	this->w = (float)1;
	this->h = (float)1;
	this->zR = 0.0f;
	init();
}
Rect::Rect(const Rect &src)
{
	m_points = NULL;
	this->x = src.X();
	this->y = src.Y();
	this->w = src.W();
	this->h = src.H();
	this->zR = src.GetRotation();
	init();
}
void Rect::operator=(const Rect &src)
{
	destroy();
	m_points = NULL;
	this->x = src.X();
	this->y = src.Y();
	this->w = src.W();
	this->h = src.H();
	this->zR = src.GetRotation();
	init();
}
Rect::Rect(int x, int y, int w, int h)
{
	m_points = NULL;
	this->x = (float)x;
	this->y = (float)y;
	this->w = (float)w;
	this->h = (float)h;
	this->zR = 0.0f;
	init();
}
Rect::Rect(int x, int y, int w, int h, float zRotation)
{
	m_points = NULL;
	this->x = (float)x;
	this->y = (float)y;
	this->w = (float)w;
	this->h = (float)h;
	this->zR = zRotation;
	init();
}
Rect::Rect(float x, float y, float w, float h)
{
	m_points = NULL;
	this->x = x;
	this->y = y;
	this->w = w;
	this->h = h;
	this->zR = 0.0f;
	init();
}
Rect::Rect(float x, float y, float w, float h, float zRotation)
{
	m_points = NULL;
	this->x = x;
	this->y = y;
	this->w = w;
	this->h = h;
	this->zR = zRotation;
	init();
}
Rect::~Rect()
{
	destroy();	
}
void Rect::init()
{
	m_origin = vector2(w/2, h/2);
	m_points = new vector2[4];
	UpdatePoints();
}
void Rect::UpdatePoints()
{
	m_points[0] = vector2(0.0f, 0.0f).Translate(-m_origin).Rotate(zR).Translate(m_origin.x + x, m_origin.y + y);
	m_points[1] = vector2(w, 0.0f).Translate(-m_origin).Rotate(zR).Translate(m_origin.x + x, m_origin.y + y);
	m_points[2] = vector2(w, h).Translate(-m_origin).Rotate(zR).Translate(m_origin.x + x, m_origin.y + y);
	m_points[3] = vector2(0.0f, h).Translate(-m_origin).Rotate(zR).Translate(m_origin.x + x, m_origin.y + y);
}
void Rect::destroy()
{
	if(m_points != NULL)
	{
		delete[] m_points;
		m_points = NULL;
	}
}
void Rect::SetOrigin(vector2 origin)
{
	m_origin = origin;
	UpdatePoints();
}
void Rect::SetOrigin(float x, float y)
{
	m_origin = vector2(x, y);
	UpdatePoints();
}
vector2 Rect::GetOrigin() const
{
	return m_origin;
}
bool Rect::CollidesWith(const Rect &other)
{
	//Axis-aligned collision
	if((this->zR == 0.0f) && (other.zR == 0.0f))
	{
		if((this->x + this->w) < other.x)
			return false;
		if((this->y + this->h) < other.y)
			return false;
		if(this->x > (other.x + other.w))
			return false;
		if(this->y > (other.y + other.h))
			return false;
		return true;
	}

	//Non Axis-aligned collision
	
}
Rect Rect::CreateAxisAlignedBoundingBox()
{
	float xMin = m_points[0].x;
	float xMax = m_points[0].x;
	float yMin = m_points[0].y;
	float yMax = m_points[0].y;
	for(int i = 1; i < 4; i++)
	{
		xMin = min(xMin, m_points[i].x);
		yMin = min(yMin, m_points[i].y);
		xMax = max(xMax, m_points[i].x);
		yMax = max(yMax, m_points[i].y);
	}
	Rect _tmp(xMin, yMin, xMax, yMax);
	return _tmp;
}